package com.lingx.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import javax.annotation.Resource;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.lingx.model.IInterpreter;
import com.lingx.model.impl.DefaultEntity;
import com.lingx.model.impl.DefaultField;
import com.lingx.utils.Utils;
@Component("lingxInterpretService")
public class InterpretService {
	/**
	 * 缓存数据库取出的数据
	 */
	private static Cache<String, List<Map<String,Object>>> CACHE=CacheBuilder.newBuilder().maximumSize(100000).expireAfterWrite(1, TimeUnit.MINUTES).build();
	
	@Resource
	private ModelService modelService;
	@Resource
	private JdbcTemplate jdbcTemplate;
	public void inputFormat(Map<String,Object> params,List<DefaultField> fields,DefaultEntity entity){
		for(DefaultField field :fields){
			if(Utils.isNotNull(field.getInterpreter())) {
				IInterpreter inte=this.modelService.getInterpreter(field.getInterpreter());
				if(inte!=null) {
					Object value=params.get(field.getCode());
					try {
						value=inte.input(value);
						params.put(field.getCode(), value);
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}
		}
	}

	public void outputFormat(Map<String,Object> params1,List<DefaultField> fields,DefaultEntity entity){
		Map<String,Object> m=params1;
		if (m == null)
			return;
		List<Map<String,Object>> listMap=null;
		DefaultEntity subEntity=null;
		String etype=null,ename="";
		String vField=null;
		StringBuilder params=null;
		String tableName=null;
		String sql = "select `%s`,`%s` from %s where `%s`='%s' %s";
		String insql = "select `%s`,`%s` from %s where `%s` in(%s) %s";
		List<String> listField=null,paramField;

		
		for (DefaultField field : fields) {
			 if(!field.getEscape())continue;//是否转义
			listMap=null;subEntity=null;etype=null;vField=null;params=null;tableName=null; listField=null;
			 params = new StringBuilder();
			 etype = field.getRefEntity();
			 
			// if(!field.getEscape())continue;
			if (Utils.isNotNull(etype)) {
				 subEntity = modelService.getEntity(etype);
				if (subEntity == null)
					continue;
				ename=subEntity.getName();
				 tableName = subEntity.getTableName();
				 vField = modelService.getValueField(subEntity);
				listField = modelService.getTextField(subEntity);
				paramField= modelService.getParamField(subEntity);
				//System.out.println(JSON.toJSONString(paramField));
				if (m.get(field.getCode()) == null)
					continue;
				if ("tlingx_optionitem".equals(etype)) {//"sysoption".equals(field.getInputType())||
					// 当输入控件为系统选择项时，特殊处理
					params.append(
							" and option_id in(select id from tlingx_option where code='")
							.append(field.getInputOptions()).append("')");
				}
				
				try {
					List<String> allList=new ArrayList<>();
					allList.addAll(listField);
					allList.addAll(paramField);
					if (m.get(field.getCode()).toString().indexOf(",") != -1){
						//listMap =this.jdbcTemplate.queryForList(
						//		String.format(insql,this.modelService.getStringByList(allList),vField, tableName, vField,toArrayString(m.get(field.getCode())), params));
						listMap =this.getListMap(String.format(insql,this.modelService.getStringByList(allList).replaceAll(",", "`,`"),vField, tableName, vField,toArrayString(m.get(field.getCode())), params).trim());
					}else{
						//listMap = this.jdbcTemplate.queryForList(
						//		String.format(sql,this.modelService.getStringByList(allList),vField, tableName, vField,m.get(field.getCode()), params));
						listMap =this.getListMap(String.format(sql,this.modelService.getStringByList(allList).replaceAll(",", "`,`"),vField, tableName, vField,m.get(field.getCode()), params).trim());
						
					}
				} catch (Exception e) {
					e.printStackTrace();
				}

				if ("tlingx_optionitem_NO".equals(etype)) {//这里本来的处理，是为了字典在界面上不能点击，但会导致，需要该字段字时，会取不到，所以取消
					StringBuilder sb=new StringBuilder();
					if (listMap.size()>0){
						for(Map<String,Object> map:listMap){
							sb.append(map.get("name")).append(",");
						}
					}
					if(sb.length()>0){
						sb.deleteCharAt(sb.length()-1);
					}
					m.put(field.getCode(), sb.toString());
					//field.setValue(sb.toString());
				}else{
					String text="";
					if(listMap==null)listMap=new ArrayList<Map<String,Object>>();
					if (listMap.size()==0){//listMap == null
						
						Map<String,Object> map=new HashMap<String,Object>();
						map.put("text", m.get(field.getCode()));
						map.put("value", m.get(field.getCode()));
						map.put("id", m.get(field.getCode()));
						map.put("etype", etype);
						map.put("ecode", etype);
						map.put("ename", ename);
						map.put("islink", field.getIsEntityLink());
						//continue;
						//if("tlingx_optionitem".equals(etype)){
						//	map.put("text", i18n.text(map.get("text").toString(), context.getUserBean().getI18n()));
						//}
						listMap.add(map);
					}else{
						for(Map<String,Object> map:listMap){
							StringBuilder sb = new StringBuilder();
							for (String s : listField) {
								sb.append(map.get(s.toUpperCase())).append("-");
							}
							sb.deleteCharAt(sb.length() - 1);
							text=sb.toString();
							
							map.put("text", sb.toString());
							//map.put("value", m.get(field.getCode()));
							map.put("value", map.get(vField.toUpperCase()));
							map.put("etype", etype);
							map.put("ecode", etype);
							map.put("ename", ename);

							map.put("islink", field.getIsEntityLink());
							for(String str:paramField) {
								map.put(str, map.get(str));
							}
							//if("tlingx_optionitem".equals(etype)){
							//	map.put("text", i18n.text(map.get("text").toString(), context.getUserBean().getI18n()));
							//}
						}
					}
					
					m.put(field.getCode(), listMap);
					// m.put(field.getCode(), map);
					//if(field.getIsEntityLink()){//是否连接
					//	m.put(field.getCode(), listMap);
					//}else{
					//	m.put(field.getCode(), text);
						//当etype==null时，不处理引用显示，反做解释器，跟下面一样
					//	if(Utils.isNotNull(field.getInterpreter())){
					//		IInterpreter obj=this.modelService.getInterpreter(field.getInterpreter());
					//		Object val=m.get(field.getCode());
					//		try {
					//			val=obj.output(val);
					//			field.setValue(val);
					//			m.put(field.getCode(), val);
					//		} catch (Exception e) {
					//			e.printStackTrace();
					//		}
					//	}
						//field.setValue(m.get(field.getCode()));
					//}
					
					
				}
			}else{//没有指向模型时处理
				if(Utils.isNotNull(field.getInterpreter())){
					IInterpreter obj=this.modelService.getInterpreter(field.getInterpreter());
					Object val=m.get(field.getCode());
					try {
						val=obj.output(val);
						field.setValue(val);
						m.put(field.getCode(), val);
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
				
			}
		}
	}
	public List<Map<String,Object>> outputFormat(List<Map<String,Object>> list,List<DefaultField> fields,DefaultEntity entity){
		for(Map<String,Object> map:list) {
			this.outputFormat(map, fields, entity);
		}
		return list;
	}

	public static String toArrayString(Object obj){
		StringBuilder sb=new StringBuilder();
		sb.append("\"").append(obj.toString().replace(",", "\",\"")).append("\"");
		return sb.toString();
	}
	/**
	 * 2023-12-06 由于批量处理太过影响性能，所以改为缓存1分钟
	 * @param sql
	 * @return
	 */
	private List<Map<String,Object>> getListMap(String sql){
		List<Map<String,Object>> temp=null;
		if(CACHE.getIfPresent(sql)==null) {
			temp=this.jdbcTemplate.queryForList(sql);
			CACHE.put(sql, temp);
		}else {
			temp=CACHE.getIfPresent(sql);
		}
		temp= clone(temp);
		return temp;
	}
	private List<Map<String,Object>> clone(List<Map<String,Object>> list){
		List<Map<String,Object>> listNew=new ArrayList<>();
		for(Map<String,Object> map:list) {
			Map<String,Object> m=new HashMap<>();
			for(String key:map.keySet()) {
				m.put(key.toUpperCase(), map.get(key));
			}
			listNew.add(m);
		}
		return listNew;
	}
}
